﻿/*******************************************************************
Copyright (c) 2011 이재범

*  Permission is hereby granted, free of charge, to any person
*  obtaining a copy of this software and associated documentation
*  files (the "Software"), to deal in the Software without
*  restriction, including without limitation the rights to use,
*  copy, modify, merge, publish, distribute, sublicense, and/or sell
*  copies of the Software, and to permit persons to whom the
*  Software is furnished to do so, subject to the following
*  conditions:
* 
*  The above copyright notice and this permission notice shall be
*  included in all copies or substantial portions of the Software.
* 
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
*  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
*  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
*  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
*  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
*  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
*  OTHER DEALINGS IN THE SOFTWARE.
*******************************************************************/

#include "common.h"


bool is_digit(int c)
{
	if(48 <= c && c <= 57)
		return true;
	return false;
}

bool is_alpha(int c)
{
	if(65 <= c && c <= 90)
		return true;
	else if(97 <= c && c <= 122)
		return true;
	return false;
}
int find_match_parenth(int i, string &equation)
{
	int j, count = 0;
	int equation_length = equation.length();

	if(equation[i] == '(' || equation[i] == '{' )
	{
		for(j = i + 1; j < equation_length; j++)
		{
			if(equation[j] == '(' || equation[j] == '{')
				count ++;
			else if(equation[j] == ')' || equation[j] == '}')
				count --;

			if(count == -1)
				return j;
		}
	}
	else if(equation[i] == ')' || equation[i] == '}' )
	{
		for(j = i - 1; j >= 0; j--)
		{
			if(equation[j] == '(' || equation[j] == '{')
				count ++;
			else if(equation[j] == ')' || equation[j] == '}')
				count --;

			if(count == 1)
				return j;
		}
	}

	return -1; // 애러
}
int find_real_match_parenth(int i, string &equation)
{
	int j, count = 0;
	int equation_length = equation.length();

	if(equation[i] == '(' || equation[i] == '{' || equation[i] == '[' )
	{
		for(j = i + 1; j < equation_length; j++)
		{
			if(equation[j] == '(' || equation[j] == '{' || equation[j] == '[')
				count ++;
			else if(equation[j] == ')' || equation[j] == '}' || equation[j] == ']')
				count --;

			if(count == -1)
				return j;
		}
	}
	else if(equation[i] == ')' || equation[i] == '}' || equation[i] == ']')
	{
		for(j = i - 1; j >= 0; j--)
		{
			if(equation[j] == '(' || equation[j] == '{' || equation[j] == '[')
				count ++;
			else if(equation[j] == ')' || equation[j] == '}' || equation[j] == ']')
				count --;

			if(count == 1)
				return j;
		}
	}

	return -1; // 애러
}
void remove_space(string &str)
{
	string::iterator istr = str.begin();

	while (istr != str.end())
	{
		if(*istr == ' ')
		{
			str.erase(istr, istr);
			continue;
		}
		istr++;
	}
}
int search_vec(vector<string> &str, string what)
{
	vector<string>::size_type how_many = str.size();
	int i = 0;

	while (i < static_cast<int>(how_many))
	{
		if(str[i] == what)
			return i;
		i++;
	}

	return -1;
}
int search_vec(vector<string> &str, char c)
{
	string temp;

	temp = c;

	vector<string>::size_type how_many = str.size();
	int i = 0;

	while (i < static_cast<int>(how_many))
	{
		if(str[i] == temp)
			return i;
	}

	return -1;
}
void remove_space(vector<string> &str)
{
	vector<string>::iterator pointer = str.begin();
	int i = 0;

	while (pointer != str.end())
	{
		i = 0;
		while (i < static_cast<int>(pointer->length()))
		{
			if((*pointer)[i] == ' ')
			{
				pointer->erase(i, 1);
				continue;
			}
			i ++;
		}
		pointer ++;
	}
}
string vector_to_string(vector<string> &list)
{
	int i = 0;
	string str;
	while (i < static_cast<int>(list.size()))
	{
		str.append(list[i] + " ");
		i ++;
	}

	return str;
}
bool compare_vector(vector<string> &str1, vector<string> &str2)
{
	int i = 0;
	while (i < static_cast<int>(str1.size()))
	{
		if(str1[i] > str2[i])
			return true;
		else if(str1[i] < str2[i])
			return false;

		i++;
	}
	return true;
}
int find_outer_open_parenth(int i, string &equation)
{
	if(i == 0)
		return 0;

	i --;

	int count = 0;
	while (i >= 0)
	{
		if(equation[i] == '(' || equation[i] == '{')
			count ++;
		else if(equation[i] == ')' || equation[i] == '}')
			count --;

		if(count == 1)
			return i;

		i --;
	}

	return 0;
}
int find_outer_close_parenth(int i, string &equation)
{
	int equation_length = equation.length();
	if(i == equation_length - 1)
		return equation_length - 1;

	i ++;

	int count = 0;
	while (i < equation_length)
	{
		if(equation[i] == '(' || equation[i] == '{')
			count ++;
		else if(equation[i] == ')' || equation[i] == '}')
			count --;

		if(count == -1)
			return i;

		i ++;
	}

	return 0;
}
string double_to_string(double x)
{
	union convert {double z; char c[7];} num;

	num.z = x;
	string str;

	int hash;
	for(int i = 0; i < 4; i ++)
	{
		hash = num.c[2 * i] + num.c[2 * i + 1];
		if(hash == '/' || hash == ' ' || hash == '\\' || hash == '\n' || hash == EOF) // 이들은 hash 데이터에서 구분자로 사용된다!
			hash ++;
		str.push_back(hash);
	}
	return str;
} 
void remove_escape_character(string &equation)
{
	string::size_type location;

	location = equation.find("\\{");
	while (location != string::npos)
	{
		equation.replace(location, 2, "{");
		location = equation.find("\\{");
	}

	location = equation.find("\\}");
	while (location != string::npos)
	{
		equation.replace(location, 2, "}");
		location = equation.find("\\}");
	}

	location = equation.find("\\(");
	while (location != string::npos)
	{
		equation.replace(location, 2, "(");
		location = equation.find("\\(");
	}

	location = equation.find("\\)");
	while (location != string::npos)
	{
		equation.replace(location, 2, ")");
		location = equation.find("\\)");
	}
}
void optimize_braket(string &equation)
{
	int location = 0;

	while (location < static_cast<int>(equation.length()) )
	{
		if(equation[location] == '{' || equation[location] == '(')
		{
			int find = location;
			bool is_left_braket_alone = false;

			// 현재 find 에는 내가 찾은 중괄호의 위치가 저장되어 있으므로
			// 1 을 빼준다. 
			find --;
			while (find >= 0)
			{
				if(equation[find] == '{' || equation[find] == '(')
				{
					is_left_braket_alone = true;
					break;
				}
				else if(equation[find] == ' ')
				{
					find --;
					continue;
				}
				else
					break;
			}

			if(is_left_braket_alone)
			{
				// 먼저 오른쪽 괄호를 찾는다.
				int count = 0;
				find = location;

				while (find < static_cast<int>(equation.length()) )
				{
					if(equation[find] == '{' || equation[find] == '(')
						count ++;
					else if(equation[find] == '}' || equation[find] == ')')
						count --;

					if(count == 0)
						break;

					find ++;
				}

				// 현재 find 에는 내가 찾은 } 의 위치가 저장되어 있음
				int right_braket_loc = find;

				find ++;
				// 오른쪽 괄호 부터 } 다음에 바로 } 가 연속되어 나오는지 확인
				while (find < static_cast<int>(equation.length()) )
				{
					if(equation[find] == '}' || equation[find] == ')')
					{
						equation.erase(right_braket_loc, 1);
						equation.erase(location, 1);
						location --; 
						break;
					}
					else if(equation[find] == ' ')
					{
						find ++;
						continue;
					}
					else
						break;
				}
			}
		}
		location ++;
	}
}

wstring string_to_wstring_conv(string &str)
{
	wstring wstr(str.length(), L'');
	copy(str.begin(), str.end(), wstr.begin() );

	return wstr;
}
string wstring_to_string_conv(wstring &ws)
{
	string s(ws.begin(), ws.end());
	return s;
}
string convert_num_to_string(int i)
{
	std::string s;
	std::stringstream out;
	out << i;
	s = out.str();

	return s;
}